package com.panopset.refactorsf;

import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

import com.panopset.java.Version;

/**
 * Numeric document.
 *
 * <h5>References</h5>
 * <ul>
 * <li>
 * <a href="from http://www.devx.com/tips/Tip/25194"> from
 * http://www.devx.com/tips/Tip/25194</a></li>
 * </ul>
 *
 */
public final class NumericDocument extends PlainDocument {

    /**
     * Scratch buffer.
     */
    private StringBuilder scratchBuffer;

    /**
     * Constructor.
     */
    public NumericDocument() {
        scratchBuffer = new StringBuilder();
    }

    /**
     * Insert string.
     * @param offset Offset.
     * @param text Text.
     * @param aset Attribute set.
     * @throws BadLocationException Bad location exception.
     */
    public void insertString(final int offset, final String text,
            final AttributeSet aset) throws BadLocationException {
        if (text == null) {
            return;
        }

        scratchBuffer.setLength(0);

        // Reject all strings that cause the contents of the field not
        // to be a valid number (i.e., string representation of a double)
        try {
            scratchBuffer.append(getText(0, getLength()));
            scratchBuffer.insert(offset, text);
            // Kludge: Append a 0 so that leading decimal points
            // and signs will be accepted
            scratchBuffer.append('0');
        } catch (BadLocationException ble) {
            ble.printStackTrace();
            return;
        } catch (StringIndexOutOfBoundsException sioobe) {
            sioobe.printStackTrace();
            return;
        }

        try {
            Double.parseDouble(scratchBuffer.toString());
        } catch (NumberFormatException nfe) {
            // Resulting string will not be number, so reject it
            return;
        }

        super.insertString(offset, text, aset);
    }

    /**
     * Serial verion id.
     */
    private static final long serialVersionUID
        = Version.UNI_VERSION;
}
